package ocbn.remotelab.events;

import ocbn.remotelab.util.date.*;

/**
 * A class for an event that is pushed to this application by the
 * server. This class cannot be instantiated directly by the client; instead,
 * a child class describing a specific event should be instantiated.
 *
 * @author Ke Li
 */
public class Event {

    private static final long DEFAULT_ID = Long.MIN_VALUE;

    /**
     * The event ID. This ID is generated on the server and is stored only
     * for the purpose of communicating with the server.
     */
    private long id;
    /**
     * The time that this event occured
     */
    private Date time;
    /**
     * A boolean indicating whether this event is important. If this is true,
     * the user will be notified immediately when this event arrives.
     */
    private boolean isImportant;

    /**
     * A String indicating the nature of the Event.
     */
    private String name;
    /**
     * Detailed information about this event
     */
    private String details;

    public Event(){
        this(DEFAULT_ID);
    }

    /**
     * Constructs an Event object from the event ID only. The time is set to the
     * current time. 
     *
     * @param id    The ID of this event
     */
    public Event(long id) {
        this(id, new Date());
    }

    /**
     * Constructs an Event object from the event ID and importance.
     * The time is set to the current time.
     *
     * @param id    The ID of this event
     * @param isImportant A boolean indicating whether this event is important
     */
    public Event(long id, boolean isImportant) {
        this(id, new Date(), isImportant);
    }

    /**
     * Constructs an Event object from the event ID and the time.
     *
     * @param id    The ID of this event
     * @param time  A Date object indicating the time this event occured
     */
    public Event(long id, Date time) {
        this(id, time, false);
    }

    /**
     * Constructs an Event object from the event ID, the time and the
     * importance.
     *
     * @param id            The ID of this event
     * @param time          A Date object indicating the time this event occured
     * @param isImportant   A boolean indicating whether this event is important
     */
    public Event(long id, Date time, boolean isImportant) {
        this.id = id;
        this.time = time;
        this.isImportant = isImportant;
        this.details = "";

    }

    /**
     * Retrieves this event's ID.
     *
     * @return  The event ID
     */
    public long getID() {
        return id;
    }

    /**
     * Sets this event's ID.
     *
     * @param id    The desired event ID
     */
    public void setID(long id) {
        this.id = id;
    }

    /**
     * Retrieves the time this event occured.
     *
     * @return  A Date object indicating the time this event occured
     */
    public Date getTime() {
        return time;
    }

    /**
     * Sets the time this event occured.
     *
     * @param time  A Date object indicating the time this event occured
     */
    public void setTime(Date time) {
        this.time = time;
    }

    /**
     * Retrieves the type of this event.
     *
     * @return  A Class object representing the type of the event
     */
    public Class getType() {
        return this.getClass();
    }

    /**
     * Retrieves the importance of this event.
     *
     * @return  A boolean indicating whether this event is important
     */
    public boolean isImportant() {
        return isImportant;
    }

    /**
     * Sets the importance of this event. 
     *
     * @param isImportant   A boolean indicating whether this event is important
     */
    public void setImportance(boolean isImportant) {
        this.isImportant = isImportant;
    }

    /**
     * Converts this event to String.
     *
     * @return  A String containing information about this object
     */
    public String toString() {
        String str = "";
        if (isImportant()) {
            str += "Important event";
        } else {
            str += "Event";
        }
        str += " occured at " + time + " with the ID of " + id;
        return str;
    }

    /**
     * Get the name of the Event.
     * @return the name of the Event in a String.
     */
    public String getName() {
        return name;
    }

    /**
     * Set the name of the Event.
     * @param name the name to be set.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Checks if the event has detailed information.
     *
     * @return  A boolean indicating whether the event has detailed information
     */
    public boolean hasDetails() {
        return !details.equals("");
    }

    /**
     * Sets event details to a custom string.
     *
     * @param details   A String containing the desired event details
     */
    public void setDetails(String details) {
        this.details = details;
    }

    /**
     * Gets event details as a String.
     * @return a String containing the event details.
     */
    public String getDetails() {
        return this.details;
    }
}
